home *** CD-ROM | disk | FTP | other *** search
- #import "ColumnMatrix.h"
- #import "Article.h"
- #import "MatrixSet.h"
- #include <assert.h>
- #import "instr.h"
- #import "regexpr.h"
- #import "MatrixScroller.h"
-
- @implementation ColumnMatrix
-
- #define MOD(a,b) ((a)<0)? ((a)+(b))%(b) : (a)%(b)
-
- - awakeFromNib
- {
- buttonTitle=NXCopyStringBuffer([selectionButton title]);
- return self;
- }
-
- - free
- {
- if(myVisibleCellList!=nil)
- [myVisibleCellList free];
- free(buttonTitle);
- return [super free];
- }
-
- - initFrame:(const NXRect *)frameRect
- {
- NXSize newIntercell = {0.0, 0.0};
- NXSize newCellSize;
-
- [super initFrame:frameRect mode:NX_LISTMODE prototype:[Cell new] numRows:0 numCols:0];
- [protoCell setBordered:FALSE];
- [protoCell setAlignment:NX_LEFTALIGNED];
-
- newCellSize.height=16.0;
- newCellSize.width = frameRect->size.width;
-
- [self setCellSize:&newCellSize];
- [self setIntercell:&newIntercell];
- [self setBackgroundGray:NX_LTGRAY];
- [self setAutoscroll:TRUE];
-
- return self;
- }
-
- - superviewSizeChanged:(const NXSize*)oldSize
- {
- NXSize newCellSize;
- NXRect aRect;
-
- [super superviewSizeChanged:oldSize];
-
- [superview getFrame:&aRect];
-
- newCellSize.width = aRect.size.width;
- newCellSize.height = cellSize.height;
- [self setCellSize:&newCellSize];
- [self sizeToCells];
- return self;
- }
-
- - scrollUp
- {
- NXSize visibleSize;
- NXRect theUpperRect;
-
- [[[self superview] superview] getContentSize:&visibleSize];
- NXSetRect(&theUpperRect,0.0,0.0,visibleSize.width,visibleSize.height);
- [self scrollRectToVisible:&theUpperRect];
-
- return self;
- }
-
- - loadMatrix
- {
- int i,j;
-
- for(i=numRows-1;i>=0;i--)
- [self removeRowAt:i andFree:NO];
- [self makeVisibleCellList:self];
- j=[myVisibleCellList count];
- for(i=0;i<j;i++)
- [self addRow];
- [self sizeToCells];
- [self clearSelectedCell];
-
- return self;
- }
-
- - reloadMatrix
- {
- List *selList;
- int lastCellPos=NX_NOT_IN_LIST;
- int i,j;
-
- selList=[self getSelectedCells:nil];
- [self loadMatrix];
- if(selList==nil)
- return self;
- j=[selList count];
- for(i=0;i<j;i++){
- id aCell=[selList objectAt:i];
- if([aCell isTaged]==TRUE){
- int pos=[cellList indexOf:aCell];
- if(pos!=NX_NOT_IN_LIST){
- [self setSelectionFrom:pos to:pos anchor:pos lit:YES];
- lastCellPos=pos;
- }
- }
- }
- [selList free];
- if(lastCellPos!=NX_NOT_IN_LIST)
- [self scrollCellToVisible:lastCellPos upperOffset:1.5 lowerOffset:1.5];
-
- return self;
- }
-
- - setMatrixCellList:(List *)aList
- {
- myCellList=aList;
- return self;
- }
-
- - makeVisibleCellList:sender
- {
- int i,j;
-
- if(myVisibleCellList!=nil)
- [myVisibleCellList free];
- myVisibleCellList=[[List alloc] init];
- j=[myCellList count];
- for(i=0;i<j;i++){
- id aCell=[myCellList objectAt:i];
- if([aCell isTaged]==TRUE)
- [myVisibleCellList addObject:aCell];
- }
- return self;
- }
-
-
- - makeCellAt:(int)row :(int)col
- {
- assert(col==0);
- return [myVisibleCellList objectAt:row];
- }
-
- - (id)selectionButton
- {
- return selectionButton;
- }
-
- - removeInvalidCell:aCell
- {
- return [self removeInvalidCell:aCell andUpdate:YES];
- }
-
- - removeInvalidCell:aCell andUpdate:(BOOL)update
- {
- int pos=[cellList indexOf:aCell];
-
- [myCellList removeObject:aCell];
- [myVisibleCellList removeObject:aCell];
- if(pos==NX_NOT_IN_LIST){
- NX_ASSERT(pos==NX_NOT_IN_LIST,"Internal DS mismatch");
- return self;
- }
- [self removeRowAt:pos andFree:YES];
- if(update==YES)
- [self update];
- return self;
- }
-
- - update
- {
- [self reloadMatrix];
- [self display];
- [mySet sync];
- [NXApp updateWindows];
-
- return self;
- }
-
- - setButtonTitle:(const char *)title
- {
- free(buttonTitle);
- [selectionButton setTitle:title];
- buttonTitle=NXCopyStringBuffer(title);
-
- return self;
- }
-
- - _delayedUpdate:sender
- {
- [selectionButton setTitle:buttonTitle];
- return self;
- }
-
- - updateButtonTitle
- {
- [self perform:@selector(_delayedUpdate:) with:self afterDelay:0.0 cancelPrevious:TRUE];
- return self;
- }
-
- - (List *)getCurrSelections
- {
- return [self getSelectedCells:nil];
- }
-
- - currSelection
- {
- return [self selectedCell];
- }
-
- - (BOOL)selectNextCell:(int)delta
- {
- int i,j;
- id cSel;
-
- NX_ASSERT(((delta==1) || (delta==-1)),"Wrong parameter selectNextCell");
-
- j=[myVisibleCellList count];
- if(j==0)
- return FALSE;
-
- if((cSel=[mySet currentSelection])!=nil){
- i=[myVisibleCellList indexOf:cSel];
- NX_ASSERT(i!=NX_NOT_IN_LIST,"Internal DS mismatch");
- if((delta>0) && (i==j-1))
- return FALSE; //last article
- else
- if((delta<0) && (i==0))
- return FALSE; //first article
- }
- else
- if(delta>0)
- i=-1;
- else
- i=j;
-
- [self selectCellAt:i+delta :0];
- [self scrollCellToVisible:i+delta upperOffset:((delta==-1)? 1.5:0.0) lowerOffset:((delta==1)? 1.5:0.0)];
- [self sendAction];
-
- return TRUE;
- }
-
- - selectAll:sender
- {
-
- [super selectAll:sender];
- [self sendAction];
-
- return self;
- }
-
- - mySet
- {
- return mySet;
- }
-
- //-------------------------
- // searchable text protocol
- //-------------------------
-
- - (oneway void)makeSelectionVisible
- {
- id selCell=[self selectedCell];
-
- if(selCell!=nil)
- [self scrollCellToVisible:[[self cellList] indexOf:selCell]
- upperOffset:(findNext? 0.0:1.5) lowerOffset:(findNext? 1.5:0.0)];
- }
-
- - (int)replaceAll:(const char *)pattern with:(const char *)replacement mode:(SearchMode)mode regexpr:(BOOL)regexpr cases:(BOOL)cases
- {
- return SEARCH_CANNOT_WRITE;
- }
-
- - (oneway void)replaceSelection:(const char *)replacement
- {
- }
-
- - (const char *)stringValueForCellAt:(int)index
- {
- return [[self cellAt:index :0] stringValue];
- }
-
- - (int)searchFor:(const char *)pattern mode:(SearchMode)mode reverse:(BOOL)rev regexpr:(BOOL)regexpr cases:(BOOL)cases position:(out int *)pos size:(out int *)size
- {
- int rows,cols,i;
- int s_pos;
- int fStart,fEnd;
- int delta;
-
- unsigned char fm[256], tr[256];
- struct re_pattern_buffer rpat;
-
- findNext=!rev;
-
- s_pos=-2;
- fStart=fEnd=-2;
-
- [self getNumRows:&rows numCols:&cols];
- if(rows==0)
- return 0;
-
- // find first selected cell
- for(i=0;i<rows;i++)
- if([[self cellAt:i :0] state]){
- s_pos=i;
- break;
- }
-
- if(!rev){
- if(s_pos<0){
- fStart=0; fEnd=rows;
- }
- else{
- fStart=s_pos+1; fEnd=s_pos+rows;
- }
- }
- else{
- if(s_pos<0){
- fStart=rows-1; fEnd=-1;
- }
- else{
- fStart=s_pos-1+rows; fEnd=s_pos;
- }
- }
-
- delta= rev? -1:1;
-
- if(regexpr){
- char *str;
- int i;
-
- memset(&rpat, 0, sizeof(rpat));
- for(i=256; i--;)
- tr[i] = i;
- if(!cases)
- for(i='A'; i<='Z'; i++)
- tr[i] = i-'A'+'a';
- rpat.translate = tr;
- rpat.fastmap = fm;
- str = re_compile_pattern((char *)pattern,strlen(pattern), &rpat);
- if (str!=NULL)
- return (strcmp(str, "Out of memory")?SEARCH_INVALID_REGEXPR:SEARCH_INTERNAL_ERROR);
- }
-
- for(;fStart!=fEnd;fStart+=delta){
- int index=fStart%rows;
- const char *result=NULL;
- const char *cellString=[self stringValueForCellAt:index];
-
- if(regexpr){
- int l=strlen(cellString);
- int p=re_search_pattern(&rpat,(char *)cellString,l,0,l,0);
-
- if(p==-2)
- return SEARCH_INTERNAL_ERROR;
- result= (p==-1)? NULL : cellString;
- }
- else
- result=instr(cellString,pattern,cases);
-
- if(result!=NULL){
- *pos=index;
- *size=1;
- return 1;
- }
- }
-
- return 0;
- }
-
- - (oneway void)selectTextFrom:(int)start to:(int)end
- {
- int rows,cols;
- if(start<=end){
- if(start==end){
- [self selectCellAt:-1 :-1];
- [self sendAction];
- }
- else{
- [self getNumRows:&rows numCols:&cols];
- if(end<=rows){
- [self selectCellAt:start :0];
- [self sendAction];
- }
- }
- }
- }
-
- - (void)writeSelectionToPasteboard:(in Pasteboard *)pboard asType:(in NXAtom)type
- {
- id aList =[self getCurrSelections];
-
-
- if([aList count]==1){
- const char *sval=[[aList objectAt:0] stringValue];
- [pboard declareTypes:&type num:1 owner:NULL];
- [pboard writeType:type data:sval length:strlen(sval)];
- }
- [aList free];
-
- return;
- }
-
- @end
-